#include <iostream>

using namespace std;

/*
 * 普通函数和函数模板的调用规则
 *      1、如果函数模板和普通函数都可以实现，优先调用普通函数
 *      2、可以通过空模板参数列表来强制调用函数模板
 *      3、函数模板也可以发生重载
 *      4、如果函数模板可以产生更好的匹配，优先调用函数模板
 */

void myPrint(int a, int b){
    cout << "普通的函数" << endl;
}

template<class T>
void myPrint(T a, T b){
    cout << "函数模板" << endl;
}

template<class T>
void myPrint(T a, T b, T c){
    cout << "函数模板重载" << endl;
}

void test01(){
    int a = 10;
    int b = 10;
    myPrint(a, b);   // 优先调用普通函数

    myPrint<>(a, b);   // 空模板参数列表强制调用函数模板


    myPrint<>(a, b, 100);   // 函数模板重载

    char c1 = 'a';
    char c2 = 'b';
    myPrint(c1, c2);   // 更好的匹配
}

class Person{
public:
    Person(string name, int age){
        this->p_name = name;
        this->age = age;
    }
    string p_name;
    int age;
};

template<class T>
bool compare(T &a, T &b){
    if(a == b){
        return true;
    }
    return false;
}

// 解决上面的compare函数不知道如何对比两个Person类是否相等的问题
//利用具体化Person的版本实现代码，具体化优先调用
template<> bool compare(Person &p1, Person &p2){
    if(p1.p_name == p2.p_name && p1.age == p2.age){
        return true;
    }
    return false;
}

int main() {

    test01();

    return 0;
}
